package TransportProblem;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author HP-Raul
 *
 */
/**
 * @author HP-Raul
 * 
 */
public class Data {

	private int vehicle; // Anzahl der Fahrzeuge
	private int dim;
	private int maxQ; // maximale Kapazität
	private int maxTime;
	private int dropTime;
	private double[][] distanceMatrix;
	private Map<Integer, Customers> inital_data_Map;
	private int steps;
	private int degradation;
	private int time;
	private int improve;
	private int shaking_rand;
	private int ls_rand;
	private LinkedList<Customers> customers;
	private String filename;
	private boolean first_Impr;

	/**
	 * Konstruktor um ein Data Objekt anzulegen
	 */
	public Data() {
		this.customers = new LinkedList<Customers>();
		this.maxTime = 999999;
		this.dim = 9;
		this.dim++;
	}

	/**
	 * Methode um die DistanzMatrix zu erzeugen
	 */ 
	public void calcDistMatrix() {

		this.distanceMatrix = new double[customers.size()][customers.size()];

		for (int i = 0; i < customers.size(); i++) {
			for (int j = 0; j < customers.size(); j++) {
				this.distanceMatrix[i][j] = Math.sqrt(Math.pow((customers.get(i).getX() - customers.get(j).getX()), 2)
						+ Math.pow((customers.get(i).getY() - customers.get(j).getY()), 2));
			}
		}

	}

	/**
	 * Methode um die Angegebene Datei auszulesen. Es wird Ein Custoer aus den
	 * Werten erstellt und in die Liste gespeichert
	 * 
	 * @param filename
	 */
	public void readData(String filename) {
		this.filename = filename;
		FileReader fr;
		try {
			fr = new FileReader(this.filename);

			BufferedReader br = new BufferedReader(fr);

			String zeile = br.readLine();

			for (int i = 0; i < 3; i++) {
				br.readLine();
			}// �berspringen bis Vehicle

			/* Parsen aller Zahlen im TXT */
			zeile = br.readLine();
			// System.out.println(zeile);
			Pattern p = Pattern.compile("(\\d+\\.?\\d*)");
			Matcher m = p.matcher(zeile);

			/* Filtern der ersten bei den Zahlen f�r Vehicle und Kapazit�t */
			int j = 1;
			while (m.find()) {
				if (j == 1) {
					this.vehicle = Integer.parseInt(m.group());
				} else if (j == 2) {
					this.maxQ = Integer.parseInt(m.group());
				}
				j++;
			}

			System.out.println("Vehicle: " + this.vehicle + "\n" + "Capacity: "
					+ this.maxQ);

			for (int i = 0; i < 4; i++) {
				br.readLine();
			}// �berspringen bis Customer

			int i = 1; // z�hler f�r Customers
			int name = 0;
			double x = 0;
			double y = 0;
			int demand = 0;
			int readyTime = 0;
			int dueDate = 0;
			int serviceTime = 0;

			/* Alle customer Z�hlen und in die Liste hinzuf�gen */
			while ((zeile = br.readLine()) != null) {
				// System.out.println("Gelesene aktuelle Zeile: " + zeile);

				// aktuelle Zeile parsen
				p = Pattern.compile("(\\d+\\.?\\d*)");
				m = p.matcher(zeile);

				while (m.find()) {
					switch (i) {
					case 1:
						name = Integer.parseInt(m.group());
						break;
					case 2:
						x = Double.parseDouble(m.group());
						break;
					case 3:
						y = Double.parseDouble(m.group());
						break;
					case 4:
						demand = (int) Double.parseDouble(m.group());
						break;
					case 5:
						readyTime = (int) Double.parseDouble(m.group());
						break;
					case 6:
						dueDate = (int) Double.parseDouble(m.group());
						break;
					case 7:
						serviceTime = (int) Double.parseDouble(m.group());

						// Benutzer erstellen und hinzuf�gen
						name--;
						Customers cNew = new Customers(name, x, y, demand,
								readyTime, dueDate, serviceTime);
						addCustomerToList(cNew);

						i = 0;// wie beim Anfang der Zeile beginnen
						break;
					default:
						System.out.println("Fehler beim Filtern der Customer");
					}// Filtern der einzelnen Attribute eines Customers

					i++;
				}
			}

			br.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block

			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * Alle Customers Ausgeben lassen
	 */
	public void printAllCustomers() {
		System.out.println();
		if (this.customers != null) {
			for (int i = 0; i < this.customers.size(); i++) {
				System.out.println("Customer: "
						+ this.customers.get(i).toString());
			}
		}
	}

	/**
	 * Customer c zur customers Liste hinzuf�gen
	 * 
	 * @param c
	 */
	public void addCustomerToList(Customers c) {
		this.customers.add(c);
	}

	/**
	 * Gibt einen bestimmten Customer mittels seinem Namen zur�ck
	 * 
	 * @param cName
	 * @return
	 */
	public Customers getCustomerByName(int cName) {
		if (this.customers.contains(this.customers.get(cName)) == false) {
			return null;
		} else
			return this.customers.get(cName);
	}

	/**
	 * L�scht einen Customer mit den angegebenen Namen
	 * 
	 * @param cName
	 */
	public void deleteSpecificCustomerByName(int cName) {
		this.customers.remove(cName);
	}

	public int getVehicle() {
		return vehicle;
	}

	public void setVehicle(int vehicle) {
		this.vehicle = vehicle;
	}

	public int getDim() {
		return dim;
	}

	public void setDim(int dim) {
		this.dim = dim;
	}

	public int getMaxQ() {
		return maxQ;
	}

	public void setMaxQ(int maxQ) {
		this.maxQ = maxQ;
	}

	public int getMaxTime() {
		return maxTime;
	}

	public void setMaxTime(int maxTime) {
		this.maxTime = maxTime;
	}

	public int getDropTime() {
		return dropTime;
	}

	public void setDropTime(int dropTime) {
		this.dropTime = dropTime;
	}

	public double[][] getDistanceMatrix() {
		return distanceMatrix;
	}

	public void setDistanceMatrix(double[][] distanceMatrix) {
		this.distanceMatrix = distanceMatrix;
	}

	public Map<Integer, Customers> getInital_data_Map() {
		return inital_data_Map;
	}

	public void setInital_data_Map(Map<Integer, Customers> inital_data_Map) {
		this.inital_data_Map = inital_data_Map;
	}

	public LinkedList<Customers> getCustomers() {
		return customers;
	}

	public void setCustomers(LinkedList<Customers> customers) {
		this.customers = customers;
	}

	public int getSteps() {
		return steps;
	}

	public void setSteps(int steps) {
		this.steps = steps;
	}

	public int getDegradation() {
		return degradation;
	}

	public void setDegradation(int degradation) {
		this.degradation = degradation;
	}

	public int getTime() {
		return time;
	}

	public void setTime(int time) {
		this.time = time;
	}

	public int getImprove() {
		return improve;
	}

	public void setImprove(int improve) {
		this.improve = improve;
	}

	public int getShaking_rand() {
		return shaking_rand;
	}

	public void setShaking_rand(int shaking_rand) {
		this.shaking_rand = shaking_rand;
	}

	public int getLs_rand() {
		return ls_rand;
	}

	public void setLs_rand(int ls_rand) {
		this.ls_rand = ls_rand;
	}

	public boolean isFirst_Impr() {
		return first_Impr;
	}

	public void setFirst_Impr(boolean first_Impr) {
		this.first_Impr = first_Impr;
	}

}
